package QueryPlan;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;

import Agent.ObjectAgent;

import com.mysql.jdbc.Connection;
import com.mysql.jdbc.ResultSet;
import com.mysql.jdbc.Statement;

public class QueryPlanBuilder {
	//variaveis de conexão com o banco
	private Connection conn;
	private Statement statement;
	private ResultSet result; 
		
	
	public QueryPlanBuilder() throws ClassNotFoundException, SQLException{        
        connectDB();
	}

	private void connectDB() throws ClassNotFoundException, SQLException {
		Class.forName("com.mysql.jdbc.Driver");
	    setConn((Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/tpch?autoReconnect=true","tpch","root"));
	    DriverManager.setLoginTimeout(10000);
	    setStatement((Statement) getConn().createStatement());
	}
	
	public ArrayList<String> buildPlan(double quantum, String fileQuery) throws SQLException, IOException{
		
		BufferedReader in = new BufferedReader(new FileReader(fileQuery));
	    String query;
	   
	    if((query = in.readLine())!=null) in.close();
	    else throw new IOException("Arquivo sem consulta!");
	    
		ArrayList<String> queries = new ArrayList<String>();
		result = (ResultSet) statement.executeQuery("explain "+query);
		getResult().first();
		String key = result.getString("key");
		if(key==null){
								
			int i1 = query.indexOf(">");
			int i2 = query.indexOf(" and");
			int inicialValue = Integer.parseInt(query.substring(i1+1, i2));
			
			int i3 = query.indexOf("<=");
			String pred = query.substring(i2+5,i3);
			i2 = query.indexOf(";");
			int finalValue = Integer.parseInt(query.substring(i3+2, i2));
			
			query = query.substring(0, i1); //str = select..from..
					
			//construindo consultas do novo plano
			String q1;
			int med1=finalValue-inicialValue;
			int tpsQuantum = (int) (med1/quantum);
			
			if(tpsQuantum<quantum) tpsQuantum=(int) quantum;
			do {					
				if(med1>tpsQuantum){
					q1 = query.concat(">"+inicialValue+" and "+pred+"<="+(tpsQuantum+inicialValue)+";");
					result = (ResultSet) statement.executeQuery("explain "+q1);
					getResult().first();
					key = result.getString("key");
					if(key==null){
						queries.addAll(buildPlan(quantum,q1));
					}
					else queries.add(q1);
					inicialValue += tpsQuantum; 
					med1-=tpsQuantum;
				}
				else{
					q1 = query.concat(">"+inicialValue+" and "+pred+"<="+(med1+inicialValue)+";");
					result = (ResultSet) statement.executeQuery("explain "+q1);
					getResult().first();
					key = result.getString("key");
					if(key==null){
						queries.addAll(buildPlan(quantum,q1));
					}
					else queries.add(q1);
					med1 = 0;
					break;
				}
				
			}while(med1!=0);
		}
		return queries;
	}
	

	public Connection getConn() {
		return conn;
	}

	public void setConn(Connection conn) {
		this.conn = conn;
	}

	public Statement getStatement() {
		return statement;
	}

	public void setStatement(Statement statement) {
		this.statement = statement;
	}

	public ResultSet getResult() {
		return result;
	}

	public void setResult(ResultSet result) {
		this.result = result;
	}
	
	
}
